home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
programming
/
other
/
jikes
/
src
/
getclass.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
45KB
|
1,118 lines
// $Id: getclass.cpp,v 1.7 1999/03/09 14:37:17 shields Exp $
//
// This software is subject to the terms of the IBM Jikes Compiler
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1998, International Business Machines Corporation
// and others. All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
#include "config.h"
#include <sys/stat.h>
#include "control.h"
#include "semantic.h"
#include "access.h"
#include "getclass.h"
#include "zip.h"
inline u1 Semantic::GetU1(char *buffer)
{
return *buffer;
}
inline u2 Semantic::GetU2(char *buffer)
{
u2 i = (u1) *buffer++;
return (i << 8) + (u1) *buffer;
}
inline u4 Semantic::GetU4(char *buffer)
{
u4 i = (u1) *buffer++;
i = (i << 8) + (u1) *buffer++;
i = (i << 8) + (u1) *buffer++;
return (i << 8) + (u1) *buffer;
}
inline u1 Semantic::GetAndSkipU1(char *&buffer)
{
return (u1) *buffer++;
}
inline u2 Semantic::GetAndSkipU2(char *&buffer)
{
u2 i = (u1) *buffer++;
return (i << 8) + (u1) *buffer++;
}
inline u4 Semantic::GetAndSkipU4(char *&buffer)
{
u4 i = (u1) *buffer++;
i = (i << 8) + (u1) *buffer++;
i = (i << 8) + (u1) *buffer++;
return (i << 8) + (u1) *buffer++;
}
inline void Semantic::Skip(char *&buffer, int n)
{
buffer += n;
}
TypeSymbol *Semantic::ProcessNestedType(TypeSymbol *base_type, NameSymbol *name_symbol, LexStream::TokenIndex tok)
{
TypeSymbol *inner_type = base_type -> FindTypeSymbol(name_symbol);
if (! inner_type)
{
int length = base_type -> ExternalNameLength() + 1 + name_symbol -> NameLength(); // +1 for $,... +1 for $
wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
wcscpy(external_name, base_type -> ExternalName());
wcscat(external_name, StringConstant::US__DS_);
wcscat(external_name, name_symbol -> Name());
NameSymbol *external_name_symbol = control.FindOrInsertName(external_name, length);
delete [] external_name;
inner_type = base_type -> InsertNestedTypeSymbol(name_symbol);
inner_type -> outermost_type = base_type -> outermost_type;
inner_type -> supertypes_closure = new SymbolSet;
inner_type -> subtypes = new SymbolSet;
inner_type -> SetExternalIdentity(external_name_symbol);
inner_type -> SetOwner(base_type);
inner_type -> SetSignature(control);
FileSymbol *file_symbol = Control::GetFile(base_type -> ContainingPackage(), external_name_symbol, control.option.depend);
if (file_symbol)
{
inner_type -> file_symbol = file_symbol;
inner_type -> SetLocation();
ReadClassFile(inner_type, tok);
}
else
{
inner_type -> SetSymbolTable(1); // this symbol table will only contain a default constructor
inner_type -> super = control.Object();
inner_type -> MarkBad();
AddDefaultConstructor(inner_type);
ReportSemError(SemanticError::TYPE_NOT_FOUND,
tok,
tok,
inner_type -> ContainingPackage() -> PackageName(),
inner_type -> ExternalName());
}
}
return inner_type;
}
TypeSymbol *Semantic::RetrieveNestedTypes(TypeSymbol *base_type, wchar_t *signature, LexStream::TokenIndex tok)
{
int len;
for (len = 0; signature[len] != U_NULL && signature[len] != U_DOLLAR; len++)
;
NameSymbol *name_symbol = control.FindOrInsertName(signature, len);
TypeSymbol *inner_type = ProcessNestedType(base_type, name_symbol, tok);
return (signature[len] == U_DOLLAR ? RetrieveNestedTypes(inner_type, &signature[len + 1], tok) : inner_type);
}
TypeSymbol *Semantic::ReadType(TypeSymbol *base_type, wchar_t *signature, LexStream::TokenIndex tok)
{
int total_length;
for (total_length = 0; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
;
if (signature[total_length] != U_NULL && Code::IsDigit(signature[total_length + 1])) // an anonymous or a local type?
{
for (total_length += 2; Code::IsDigit(signature[total_length]); total_length++) // will stop at next '$' or '\0' !!!
;
if (signature[total_length] != U_NULL) // not an anonymous type ? then, it's a local type: scan local name
{
for (total_length++; signature[total_length] != U_NULL && signature[total_length] != U_DOLLAR; total_length++)
;
}
}
int len;
for (len = total_length - 1; len >= 0 && signature[len] != U_SLASH; len--)
;
wchar_t *name = &(signature[len + 1]);
//
// When a package name is specified in the signature, we look for the type in question
// in that package, i.e., we redefine package. Otherwise, we search for the type in the
// unnamed package.
//
PackageSymbol *package = NULL;
//
// Which package?
//
if (len >= 0)
{
wchar_t *package_name = new wchar_t[len + 1];
for (int i = 0; i < len; i++)
package_name[i] = signature[i];
package_name[len] = U_NULL;
package = control.ProcessPackage(package_name);
if (package -> directory.Length() == 0)
{
ReportSemError(SemanticError::PACKAGE_NOT_FOUND,
tok,
tok,
package -> PackageName());
}
delete [] package_name;
}
else package = control.unnamed_package;
//
// Process type
//
NameSymbol *name_symbol = control.FindOrInsertName(name, total_length - (len + 1));
TypeSymbol *type = package -> FindTypeSymbol(name_symbol);
if (type)
{
if (type -> SourcePending())
control.ProcessHeaders(type -> file_symbol);
}
else
{
FileSymbol *file_symbol = Control::GetFile(package, name_symbol, control.option.depend);
//
// If we are dealing with the unnamed package, ...
//
if ((! file_symbol) && package == control.unnamed_package)
file_symbol = Control::GetFile(control.unnamed_package, name_symbol, control.option.depend);
//
// If a file_symbol was not found, ReadType will issue an error message
//
type = ReadType(file_symbol, package, name_symbol, tok);
//
// If we have to do a full check and we have a case where a ".class" file
// depends on a ".java" file then we should signal that the ".java" file
// associated with the ".class" file should be recompiled.
//
if (control.option.full_check && (! control.option.depend) &&
file_symbol && file_symbol -> IsJava() && (! file_symbol -> IsZip()))
{
control.recompilation_file_set.AddElement(file_symbol);
if (! control.option.incremental && control.option.pedantic)
{
ReportSemError(SemanticError::RECOMPILATION,
tok,
tok,
base_type -> ContainingPackage() -> Name(),
base_type -> ExternalName(),
type -> ContainingPackage() -> Name(),
type -> ExternalName());
}
}
}
//
// Establish a dependence from base_type (read from a class file) to type.
//
AddDependence(base_type, type, tok);
return (signature[total_length] == U_DOLLAR ? RetrieveNestedTypes(type, &signature[total_length + 1], tok) : type);
}
TypeSymbol *Semantic::ProcessSignature(TypeSymbol *base_type, char *signature, LexStream::TokenIndex tok)
{
TypeSymbol *type;
int num_dimensions = 0;
for (; *signature == U_LEFT_BRACKET; signature++)
num_dimensions++;
switch(*signature)
{
case U_B:
type = control.byte_type;
break;
case U_C:
type = control.char_type;
break;
case U_D: